package com.sl.plugin.step.db;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import com.sl.core.engine.datasource.DataSourceManager;
import com.sl.core.engine.meta.impl.AbstractProcessCompDescriptor;
import com.sl.core.engine.step.ProcessCompService;
import com.sl.core.engine.step.impl.AbstractProcessComp;
import com.sl.core.engine.utils.BeanUtil;
import lombok.SneakyThrows;
import org.apache.commons.compress.utils.Lists;
import org.beetl.sql.core.page.PageResult;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 *
 */
public class DbQueryComp extends AbstractProcessComp<List<Map<String, Object>>, List<Map<String, Object>>> implements ProcessCompService {


    public DbQueryComp(AbstractProcessCompDescriptor abstractProcessCompDescriptor) {
        super(abstractProcessCompDescriptor);
    }

    @SneakyThrows
    @Override
    public List<Map<String, Object>> input(List<Map<String, Object>> param) {
        String dataSourceId = BeanUtil.getStr(meta.getAttributeMap(), "input.dataSourceId");
        String sql = BeanUtil.getStr(meta.getAttributeMap(), "input.sql");
        Boolean pageFlag = BeanUtil.getBool(meta.getAttributeMap(), "input.pageFlag");
        if (StrUtil.isBlank(dataSourceId)) {
            return Collections.emptyList();
        }
//        String sql = BeanUtil.getStr(meta.getAttributeMap(), "input.sql");
        Boolean b = inputIsArray();
        List<Map<String, Object>> runResult = Lists.newArrayList();
        if (BooleanUtil.isFalse(b)) {
            for (Map<String, Object> pm : param) {
                Map<String, Object> map = Maps.newHashMap();
                map.put("$", pm);
                if (BooleanUtil.isTrue(pageFlag)) {
                    Map<String, Object> ps = pageQuery(pm, dataSourceId, sql, map);
                    runResult.add(ps);
                } else {
                    List<Map<String, Object>> run = DataSourceManager.INSTANCE.run(dataSourceId, sql, map);
                    runResult.addAll(run);
                }
            }
        } else {
            Map<String, Object> map = Maps.newHashMap();
            map.put("$", param);
            if (BooleanUtil.isTrue(pageFlag)) {
                Map<String, Object> pm = CollUtil.get(param, 0);
                Map<String, Object> ps = pageQuery(pm, dataSourceId, sql, map);
                runResult.add(ps);
            } else {
                List<Map<String, Object>> run = DataSourceManager.INSTANCE.run(dataSourceId, sql, map);
                runResult.addAll(run);
            }
        }
        return runResult;
    }

    private   Map<String, Object> pageQuery(Map<String, Object> pm, String dataSourceId, String sql, Map<String, Object> map) {
        Integer current = 1;
        Integer size = Integer.MAX_VALUE;
        current = MapUtil.getInt(pm, "current");
        if(ObjectUtil.isNull(current)){
            current= MapUtil.getInt(pm, "page", 1);
        }
        size = MapUtil.getInt(pm, "size");
        if(ObjectUtil.isNull(size)){
            size= MapUtil.getInt(pm, "pageSize", Integer.MAX_VALUE);
        }
        PageResult<Map<String, Object>> page = DataSourceManager.INSTANCE.page(dataSourceId, sql, map, current, size,getLogChannel());
        Map<String, Object> ps = Maps.newHashMap();
        ps.put("total", page.getTotalRow());
        ps.put("size", size);
        ps.put("current", current);
        ps.put("records", page.getList());
        return ps;
    }

}
